Skip to content

feat(tenant): TenantService + DB-backed tenant CRUD (planning §6.7)#12

Merged
jlc488 merged 1 commit into
mainfrom
feat/tenant-service
May 27, 2026
Merged

feat(tenant): TenantService + DB-backed tenant CRUD (planning §6.7)#12
jlc488 merged 1 commit into
mainfrom
feat/tenant-service

Conversation

@jlc488

@jlc488 jlc488 commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase A2 of the admin console plan. Closes the long-standing TenantService gap so the admin-ui Tenants page has something to call.

Stacked on #11.

tenant-api

  • TenantMetadata record — id + name + mode + active + createdAt
  • TenantService interface — create / rename / activate / deactivate / delete / findById / findAll

tenant-core

  • PlatformTenantEntityid varchar(64) PK (= TenantId slug, not UUID; keeps existing string-based tenant_id columns working without FK churn)
  • JpaPlatformTenantRepository
  • DefaultTenantService implementation
  • new deps: spring-boot-starter-data-jpa, Lombok (compileOnly)
  • db/migration/V7__platform_tenant.sql

autoconfigure

  • TenantAutoConfiguration grows a @ConditionalOnBean(JpaPlatformTenantRepository.class) + @ConditionalOnMissingBean TenantService bean. Apps without JPA still get TenantContextHolder + TenantResolver but no TenantService.

admin-api

  • TenantAdminController under /admin/api/v1/tenants:
    Verb Path Action
    POST / create
    GET / list
    GET /{id} fetch
    PUT /{id} rename
    PUT /{id}/activate activate
    PUT /{id}/deactivate deactivate
    DELETE /{id} delete
  • CreateTenantRequest + RenameTenantRequest DTOs (Jakarta Validation)

Design note

platform_tenant.id is a varchar(64) slug rather than UUID so existing tables that already carry tenant_id as a string slug keep working without FK migration churn. Consumer apps that want strict referential integrity can add the FK in their own migration on top.

Verified

./gradlew :devslab-kit-sample-app:test  → BUILD SUCCESSFUL in 56s
  • V7 applies cleanly on top of V1-V6
  • TenantService bean wires
  • All previous beans + login flow + admin-api controllers still green

Phase A2 of the admin console plan — closes the long-standing
TenantService gap so the admin-ui Tenants page has something to call.

tenant-api:
- TenantMetadata (record: id + name + mode + active + createdAt)
- TenantService (interface: create / rename / activate / deactivate /
  delete / findById / findAll)

tenant-core:
- PlatformTenantEntity (id varchar(64) PK = TenantId slug,
  name, mode (SINGLE/MULTI), active, created_at)
- JpaPlatformTenantRepository
- DefaultTenantService implementation
- new deps: spring-boot-starter-data-jpa, lombok (compileOnly)
- db/migration/V7__platform_tenant.sql

autoconfigure:
- TenantAutoConfiguration grows a @ConditionalOnBean(JpaPlatformTenantRepository.class)
  + @ConditionalOnMissingBean TenantService bean. Apps without JPA on
  the classpath still get TenantContextHolder + TenantResolver but no
  TenantService.

admin-api:
- TenantAdminController under /admin/api/v1/tenants:
  POST /        create
  GET  /        list
  GET  /{id}    fetch
  PUT  /{id}    rename
  PUT  /{id}/activate, /deactivate
  DELETE /{id}
- CreateTenantRequest, RenameTenantRequest DTOs (Jakarta Validation)

Design note: platform_tenant.id stays a varchar(64) slug rather than
UUID so existing tables that already carry tenant_id as a string slug
keep working without FK migration churn. Consumer apps that want strict
referential integrity can add the FK in their own migration.

Verified: ./gradlew :devslab-kit-sample-app:test  -> BUILD SUCCESSFUL in 56s
- V7 applies cleanly on top of V1-V6
- TenantService bean wires (JpaPlatformTenantRepository present)
- All previous beans, login flow, admin-api controllers still green
@jlc488
jlc488 merged commit 500b8a0 into main May 27, 2026
1 check passed
@jlc488
jlc488 deleted the feat/tenant-service branch May 30, 2026 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant